PowerShell: Använda Packer för att skapa avbildningar av virtuella datorer i Azure
Gäller för: ✔️ Virtuella Windows-datorer
Varje virtuell dator (VM) i Azure skapas från en avbildning som definierar Windows-distributionen och os-versionen. Avbildningar kan innehålla förinstallerade program och konfigurationer. Azure Marketplace innehåller många avbildningar från första och tredje part för de vanligaste operativsystem- och programmiljöerna, eller så kan du skapa egna anpassade avbildningar som är skräddarsydda för dina behov. Den här artikeln beskriver hur du använder verktyget Packer med öppen källkod för att definiera och skapa anpassade avbildningar i Azure.
Den här artikeln testades senast den 2020-08-05 med Packer version 1.8.1.
Kommentar
Azure har nu en tjänst, Azure Image Builder, för att definiera och skapa egna anpassade avbildningar. Azure Image Builder bygger på Packer, så du kan även använda dina befintliga Packer shell provisioner-skript med det. Information om hur du kommer igång med Azure Image Builder finns i Skapa en virtuell Windows-dator med Azure Image Builder.
Skapa En Azure-resursgrupp
Under byggprocessen skapar Packer tillfälliga Azure-resurser när den skapar den virtuella källdatorn. Om du vill avbilda den virtuella källdatorn för användning som en avbildning måste du definiera en resursgrupp. Utdata från Packer-byggprocessen lagras i den här resursgruppen.
Skapa en resursgrupp med New-AzResourceGroup. I följande exempel skapas en resursgrupp med namnet myPackerGroup på platsen eastus :
$rgName = "myPackerGroup"
$location = "East US"
New-AzResourceGroup -Name $rgName -Location $location
Skapa Azure-autentiseringsuppgifter
Packer autentiserar med Azure med hjälp av tjänstens huvudnamn. Ett Huvudnamn för Azure-tjänsten är en säkerhetsidentitet som du kan använda med appar, tjänster och automatiseringsverktyg som Packer. Du styr och definierar behörigheterna för vilka åtgärder tjänstens huvudnamn kan utföra i Azure.
Skapa ett huvudnamn för tjänsten med New-AzADServicePrincipal. Värdet för -DisplayName
måste vara unikt. Ersätt med ditt eget värde efter behov.
$sp = New-AzADServicePrincipal -DisplayName "PackerPrincipal" -role Contributor -scope /subscriptions/yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy
$plainPassword = (New-AzADSpCredential -ObjectId $sp.Id).SecretText
Mata sedan ut lösenordet och program-ID:t.
$plainPassword
$sp.AppId
Om du vill autentisera till Azure måste du också hämta dina Azure-klient- och prenumerations-ID:t med Get-AzSubscription:
$subName = "mySubscriptionName"
$sub = Get-AzSubscription -SubscriptionName $subName
Definiera Packer-mall
Skapa avbildningar genom att skapa en mall som en JSON-fil. I mallen definierar du byggare och etablerare som utför själva byggprocessen. Packer har en byggare för Azure som gör att du kan definiera Azure-resurser, till exempel autentiseringsuppgifterna för tjänstens huvudnamn som skapades i föregående steg.
Skapa en fil med namnet windows.json och klistra in följande innehåll. Ange dina egna värden för följande:
Parameter | Var du kan hämta |
---|---|
client_id | Visa tjänstens huvudnamns-ID med $sp.AppId |
client_secret | Visa det automatiskt genererade lösenordet med $plainPassword |
tenant_id | Utdata från $sub.TenantId kommandot |
subscription_id | Utdata från $sub.SubscriptionId kommandot |
managed_image_resource_group_name | Namnet på resursgruppen som du skapade i det första steget |
managed_image_name | Namn på den hanterade diskbild som skapas |
{
"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 } }"
]
}]
}
Du kan också skapa en fil med namnet windows.pkr.hcl och klistra in följande innehåll med dina egna värden som används för tabellen ovan.
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 } }"]
}
}
Den här mallen skapar en virtuell Windows Server 2016-dator, installerar IIS och generaliserar sedan den virtuella datorn med Sysprep. IIS-installationen visar hur du kan använda PowerShell-etableringsverktyget för att köra ytterligare kommandon. Den sista Packer-avbildningen innehåller sedan nödvändig programinstallation och konfiguration.
Windows-gästagenten deltar i Sysprep-processen. Agenten måste vara helt installerad innan den virtuella datorn kan sysprep'ed. För att säkerställa att detta är sant måste alla agenttjänster köras innan du kör sysprep.exe. Föregående JSON-kodfragment visar ett sätt att göra detta i PowerShell-etableringen. Det här kodfragmentet krävs endast om den virtuella datorn är konfigurerad för att installera agenten, vilket är standard.
Build Packer-avbildning
Om du inte redan har Packer installerat på den lokala datorn följer du installationsanvisningarna för Packer.
Skapa avbildningen genom att öppna en cmd-prompt och ange Packer-mallfilen på följande sätt:
packer build windows.json
Du kan också skapa avbildningen genom att ange filen windows.pkr.hcl enligt följande:
packer build windows.pkr.hcl
Ett exempel på utdata från föregående kommandon är följande:
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
Det tar några minuter för Packer att skapa den virtuella datorn, köra etableringarna och rensa distributionen.
Skapa en virtuell dator från Packer-avbildningen
Nu kan du skapa en virtuell dator från avbildningen med New-AzVM. De stödjande nätverksresurserna skapas om de inte redan finns. När du uppmanas till det anger du ett administrativt användarnamn och lösenord som ska skapas på den virtuella datorn. I följande exempel skapas en virtuell dator med namnet myVM från myPackerImage:
New-AzVm `
-ResourceGroupName $rgName `
-Name "myVM" `
-Location $location `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-OpenPorts 80 `
-Image "myPackerImage"
Om du vill skapa virtuella datorer i en annan resursgrupp eller region än din Packer-avbildning anger du avbildnings-ID:t i stället för bildnamnet. Du kan hämta avbildnings-ID:t med Get-AzImage.
Det tar några minuter att skapa den virtuella datorn från Packer-avbildningen.
Testa virtuell dator och webbserver
Hämta den offentliga IP-adressen för den virtuella datorn med Get-AzPublicIPAddress. I följande exempel hämtas IP-adressen för myPublicIP som skapades tidigare:
Get-AzPublicIPAddress `
-ResourceGroupName $rgName `
-Name "myPublicIPAddress" | select "IpAddress"
Om du vill se den virtuella datorn, som innehåller IIS-installationen från Packer-etableringsverktyget, anger du i praktiken den offentliga IP-adressen i en webbläsare.
Nästa steg
Du kan också använda befintliga Packer-etableringsskript med Azure Image Builder.