Sdílet prostřednictvím


PowerShell: Použití Packeru k vytváření imagí virtuálních počítačů v Azure

Platí pro: ✔️ Virtuální počítače s Windows

Každý virtuální počítač v Azure se vytvoří z image, která definuje distribuci Windows a verzi operačního systému. Image můžou zahrnovat předinstalované aplikace a konfigurace. Azure Marketplace poskytuje řadu imagí třetích stran pro nejběžnější prostředí operačního systému a aplikací nebo si můžete vytvořit vlastní image přizpůsobené vašim potřebám. Tento článek podrobně popisuje, jak pomocí opensourcového nástroje Packer definovat a vytvářet vlastní image v Azure.

Tento článek byl naposledy testován 8.5.2020 pomocí Packer verze 1.8.1.

Poznámka:

Azure teď má službu Azure Image Builder pro definování a vytváření vlastních imagí. Azure Image Builder je založený na Packeru, takže s ním můžete dokonce použít stávající skripty zřizovacího prostředí Packeru. Pokud chcete začít pracovat s Azure Image Builderem, přečtěte si téma Vytvoření virtuálního počítače s Windows pomocí Azure Image Builderu.

Vytvoření skupiny prostředků Azure

Během procesu sestavení vytvoří Packer dočasné prostředky Azure při sestavování zdrojového virtuálního počítače. Pokud chcete zachytit zdrojový virtuální počítač pro použití jako image, musíte definovat skupinu prostředků. Výstup procesu sestavení Packeru je uložen v této skupině prostředků.

Vytvořte skupinu prostředků pomocí rutiny New-AzResourceGroup. Následující příklad vytvoří skupinu prostředků myPackerGroup v umístění eastus:

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

Vytvoření přihlašovacích údajů Azure

Packer se ověřuje v Azure pomocí instančního objektu. Instanční objekt Azure je identita zabezpečení, kterou můžete používat s aplikacemi, službami a automatizačními nástroji, jako je Packer. Řídíte a definujete oprávnění k operacím, které může instanční objekt provádět v Azure.

Vytvořte instanční objekt pomocí rutiny New-AzADServicePrincipal. Hodnota, která -DisplayName musí být jedinečná, nahraďte podle potřeby vlastní hodnotou.

$sp = New-AzADServicePrincipal -DisplayName "PackerPrincipal" -role Contributor -scope /subscriptions/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy
$plainPassword = (New-AzADSpCredential -ObjectId $sp.Id).SecretText

Pak vypíšete heslo a ID aplikace.

$plainPassword
$sp.AppId

Pokud se chcete ověřit v Azure, musíte také získat ID tenanta a předplatného Azure pomocí rutiny Get-AzSubscription:

$subName = "mySubscriptionName"
$sub = Get-AzSubscription -SubscriptionName $subName

Definování šablony Packeru

Pokud chcete vytvořit image, vytvoříte šablonu jako soubor JSON. V šabloně definujete tvůrce a zřizovací nástroje, které provádějí skutečný proces sestavení. Packer má tvůrce pro Azure , který umožňuje definovat prostředky Azure, jako jsou přihlašovací údaje instančního objektu vytvořené v předchozím kroku.

Vytvořte soubor s názvem windows.json a vložte následující obsah. Zadejte vlastní hodnoty pro následující:

Parametr Kde získat
client_id Zobrazení ID instančního objektu pomocí $sp.AppId
client_secret Zobrazení automaticky generovaného hesla pomocí příkazu $plainPassword
tenant_id Výstup z $sub.TenantId příkazu
subscription_id Výstup z $sub.SubscriptionId příkazu
managed_image_resource_group_name Název skupiny prostředků, kterou jste vytvořili v prvním kroku
managed_image_name Název vytvořené image spravovaného disku
{
  "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": "myPackerGroup",
    "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"
    },

    "build_resource_group_name": "myPackerGroup",
    "vm_size": "Standard_D2_v2"
  }],
  "provisioners": [{
    "type": "powershell",
    "inline": [
      "Add-WindowsFeature Web-Server",
      "while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
      "while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
      "& $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 } }"
    ]
  }]
}

Můžete také vytvořit soubor s názvem windows.pkr.hcl a vložit následující obsah s vlastními hodnotami, které se používají pro výše uvedenou tabulku parametrů.

source "azure-arm" "autogenerated_1" {
  azure_tags = {
    dept = "Engineering"
    task = "Image deployment"
  }
  build_resource_group_name         = "myPackerGroup"
  client_id                         = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
  client_secret                     = "ppppppp-pppp-pppp-pppp-ppppppppppp"
  communicator                      = "winrm"
  image_offer                       = "WindowsServer"
  image_publisher                   = "MicrosoftWindowsServer"
  image_sku                         = "2016-Datacenter"
  managed_image_name                = "myPackerImage"
  managed_image_resource_group_name = "myPackerGroup"
  os_type                           = "Windows"
  subscription_id                   = "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy"
  tenant_id                         = "zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz"
  vm_size                           = "Standard_D2_v2"
  winrm_insecure                    = true
  winrm_timeout                     = "5m"
  winrm_use_ssl                     = true
  winrm_username                    = "packer"
}

build {
  sources = ["source.azure-arm.autogenerated_1"]

  provisioner "powershell" {
    inline = ["Add-WindowsFeature Web-Server", "while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }", "& $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 } }"]
  }

}

Tato šablona vytvoří virtuální počítač s Windows Serverem 2016, nainstaluje službu IIS a potom zobecní virtuální počítač pomocí nástroje Sysprep. Instalace služby IIS ukazuje, jak můžete pomocí zřizovací rutiny PowerShellu spouštět další příkazy. Konečná image Packeru pak zahrnuje požadovanou instalaci a konfiguraci softwaru.

Agent hosta systému Windows se účastní procesu Sysprep. Aby mohl být virtuální počítač připravený nástrojem Sysprep, musí být agent plně nainstalovaný. Aby se zajistilo, že je to pravda, musí být před spuštěním sysprep.exe spuštěny všechny služby agenta. Předchozí fragment kódu JSON ukazuje jeden ze způsobů, jak to udělat ve zřizovacím modulu PowerShellu. Tento fragment kódu se vyžaduje jenom v případě, že je virtuální počítač nakonfigurovaný pro instalaci agenta, což je výchozí nastavení.

Image Build Packeru

Pokud na místním počítači ještě nemáte nainstalovaný Packer, postupujte podle pokynů k instalaci Packeru.

Vytvořte image tak, že otevřete příkazový řádek a zadáte soubor šablony Packeru následujícím způsobem:

packer build windows.json

Image můžete také sestavit zadáním souboru windows.pkr.hcl následujícím způsobem:

packer build windows.pkr.hcl

Příklad výstupu z předchozích příkazů je následující:

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

Sestavení virtuálního počítače, spuštění zřizovacích prostředků a vyčištění nasazení trvá několik minut.

Vytvoření virtuálního počítače z image Packeru

Teď můžete vytvořit virtuální počítač z image pomocí Rutiny New-AzVM. Podpůrné síťové prostředky se vytvoří, pokud ještě neexistují. Po zobrazení výzvy zadejte uživatelské jméno a heslo pro správu, které se má na virtuálním počítači vytvořit. Následující příklad vytvoří virtuální počítač myVM z myPackerImage:

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

Pokud chcete vytvořit virtuální počítače v jiné skupině prostředků nebo oblasti než image Packeru, místo názvu image zadejte ID image. ID image můžete získat pomocí rutiny Get-AzImage.

Vytvoření virtuálního počítače z image Packeru trvá několik minut.

Testování virtuálního počítače a webového serveru

Získejte veřejnou IP adresu virtuálního počítače pomocí rutiny Get-AzPublicIPAddress. Následující příklad získá dříve vytvořenou IP adresu pro myPublicIP:

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

Pokud chcete zobrazit virtuální počítač, který zahrnuje instalaci služby IIS ze zřizovacího nástroje Packer, v akci zadejte veřejnou IP adresu do webového prohlížeče.

Výchozí web služby IIS

Další kroky

V Azure Image Builderu můžete také použít existující skripty zřizovacího modulu Packeru.